﻿using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using élénkPróbája.native;

namespace élénkPróbája
{
    public static class ValidatorOptions
    {
        public static CascadeMode CascadeMode = CascadeMode.Continue;
        public static Type ResourceProviderType;

        private static Func<Type, MemberInfo, LambdaExpression, string> propertyNameResolver = DefaultPropertyNameResolver;
        private static Func<Type, MemberInfo, LambdaExpression, string> displayNameResolver = DefaultDisplayNameResolver;

        public static Func<Type, MemberInfo, LambdaExpression, string> PropertyNameResolver
        {
            get { return propertyNameResolver; }
            set { propertyNameResolver = value ?? DefaultPropertyNameResolver; }
        }

        public static Func<Type, MemberInfo, LambdaExpression, string> DisplayNameResolver
        {
            get { return displayNameResolver; }
            set { displayNameResolver = value ?? DefaultDisplayNameResolver; }
        }

        static string DefaultPropertyNameResolver(Type type, MemberInfo memberInfo, LambdaExpression expression)
        {
            if (expression != null)
            {
                var chain = PropChain.FromExpression(expression);
                if (chain.Count > 0) return chain.ToString();
            }

            if (memberInfo != null)
            {
                return memberInfo.Name;
            }

            return null;
        }

        static string DefaultDisplayNameResolver(Type type, MemberInfo memberInfo, LambdaExpression expression)
        {
            if (memberInfo == null) return null;
            return GetDisplayName(memberInfo);
        }

        // Nasty hack to work around not referencing DataAnnotations directly. 
        // At some point investigate the DataAnnotations reference issue in more detail and go back to using the code above. 
        static string GetDisplayName(MemberInfo member)
        {
            var attributes = (from attr in member.GetCustomAttributes(true)
                              select new { attr, type = attr.GetType() }).ToList();

            string name = null; 

            return name;
        }
    }
}